package org.jwos.plugin.file.dao;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;

import org.jwos.plugin.file.domain.FileInfo;
import org.jwos.plugin.file.domain.FolderInfo;
import org.jwos.plugin.file.domain.FolderType;
import org.jwos.plugin.file.domain.FolderViewInfo;
import org.jwos.plugin.file.domain.PublishedFileInfo;
import org.jwos.plugin.file.domain.SharedFilePermission;
import org.jwos.plugin.file.exception.DuplicateDirectoryException;
import org.jwos.plugin.file.util.ImageResizer;
import org.jwos.plugin.file.util.ObservedInputStream;

import sun.net.www.MimeTable;

public class FileManagerDAO extends JackrabbitBaseDAO {
	
	public static final String NodePath_File = "file";
	
	public void saveUserProfile(String userId,FolderViewInfo view) throws RepositoryException {
		Node userNode = this.getUserNode(userId);
		if(userNode!=null) {
			userNode.setProperty("currentFolderID", view.getCurrentFolderID());
			userNode.setProperty("parentFolderID", view.getParentFolderID());
			save();
		}
	}
	
	public void saveUserSetting(String userId,String key,String value) throws RepositoryException {
		Node userNode = this.getUserNode(userId);
		if(userNode!=null) {
			userNode.setProperty(key, value);
			save();
		}
	}
	
	public String getUserSetting(String userId,String key) throws RepositoryException {
		String value = null;
		
		Node userNode = this.getUserNode(userId);
		if(userNode!=null) {
			if(userNode.hasProperty(key)) {
				value = userNode.getProperty(key).getString();
			}			
		}
		
		return value;
	}
	
	public FolderViewInfo getUserProfile(String userId) throws RepositoryException {
		FolderViewInfo view = new FolderViewInfo();
		
		Node userNode = this.getUserNode(userId);
		if(userNode!=null) {
			if(userNode.hasProperty("currentFolderID")) {
				view.setCurrentFolderID(userNode.getProperty("currentFolderID").getString());
			}
			if(userNode.hasProperty("parentFolderID")) {
				view.setParentFolderID(userNode.getProperty("parentFolderID").getString());
			}		
		}
		
		return view;
	}
	
	public List getRecentPathList(String userId) throws RepositoryException {
		List list = new ArrayList();
		
		Node userNode = this.getUserNode(userId);
		if(userNode.hasProperty("recentPaths")) {
			Value[] values = userNode.getProperty("recentPaths").getValues();
			for(int i=0;i<values.length;i++) {
				String[] strings = values[i].getString().split(",");
				List<String> path = new ArrayList();
				//id
				path.add(strings[0]);
				//path
				path.add(strings[1]);
				list.add(path);
			}
		}
		
		return list;
	}
	
	public void saveRecentPathList(String userId,List pathList) throws RepositoryException {
		
		Node userNode = this.getUserNode(userId);
		if(pathList.size()>0) {
			String[] paths = new String[pathList.size()];
			for(int i=0;i<pathList.size();i++) {
				List list = (List)pathList.get(i);
				String id = (String)list.get(0);
				String path = (String)list.get(1);
				paths[i] = id+","+path;
			}
			userNode.setProperty("recentPaths", paths);
		}
	}
	
	public List getFileListByFolderId(String userId,String folderId) throws RepositoryException {
		List list = new ArrayList();
		
		Node node = this.getNodeById(folderId);
		if(node!=null && node.hasNodes()) {
			NodeIterator ni = node.getNodes();
			while(ni.hasNext()) {				
				FileInfo file = null;
				
				Node child = ni.nextNode();
				if(child.hasProperty("shortcut")) {
					if(child.getProperty("shortcut").getBoolean()) {
						String originalId = child.getProperty("originalId").getString();
						Node originalNode = this.getNodeById(originalId);
						if(originalNode!=null) {
							file = this.getFileInfoByNode(userId,originalNode, new FileInfo());
							file.setPath(this.getFolderPathById(userId,folderId));
						}						
					}
				} else {
					file = this.getFileInfoByNode(userId,child, new FileInfo());
				}
				
				if(file!=null) {
					list.add(file);
				}
			}
		}
		
		return list;
	}
	
	public String getFolderPathById(String userId,String folderId) throws RepositoryException {
		String path = "";
		
		Node node = this.getNodeById(folderId);
		path = this.getFolderPathByNode(userId,node, path);		
		
		return path;
	}
	
	public String getNetworkFolderPath(String userId,String ownerId,String folderId) throws RepositoryException {
		String path = "";
		
		Node node = this.getNodeById(folderId);
		Node userNode = this.getUserNode(userId);
		Node networkNode = this.getNodeByFolderType(userNode, FolderType.MyNetwork);
		Node ownerNode = networkNode.getNode(ownerId);
		
		for(NodeIterator ni=ownerNode.getNodes();ni.hasNext();) {
			Node temp = ni.nextNode();
			String originalId = temp.getProperty("originalId").getString();
			Node originalNode = this.getNodeById(originalId);
			if(originalNode.getPath().equals(node.getPath())) {
				path = this.getFolderPathById(userId,temp.getUUID());
				break;
			} else if(node.getPath().startsWith(originalNode.getPath())) {
				path = this.getFolderPathById(userId,temp.getUUID());
				path += "\\" + node.getPath().substring(originalNode.getPath().length()+1);
			}
		}
		
		return path.replaceAll("/", "\\\\");
	}
	
	public String getFileItemIdByPath(String userId,String path) {
		String id = "";
		
		try {
			path = path.replaceFirst(":", "");
			path = path.replaceAll("\\\\", "/");
			Node userNode = this.getUserNode(userId);
			
			if(path.startsWith(FolderType.FolderNames[FolderType.RootFolder])) {
				Node node = (Node)this.getSession().getItem(userNode.getPath()+"/"+path);
				
				if(node!=null) {
					if(this.isFileNode(node)) {
						id = node.getParent().getUUID();
					} else if(this.isFolderNode(node)) {
						id = node.getUUID();
					}
				}
			} else if(path.startsWith(FolderType.FolderNames[FolderType.PublishedItems])) {
				Node node = null;
				
				if(path.startsWith(FolderType.FolderNames[FolderType.PublishedItems]+"/"+FolderType.FolderNames[FolderType.PublishedFiles])) {
					node = (Node)getSession().getItem(userNode.getPath()
							+"/"+FolderType.FolderNames[FolderType.PublishedItems]
							+"/"+FolderType.FolderNames[FolderType.PublishedFiles]);
				} else if(path.startsWith(FolderType.FolderNames[FolderType.PublishedItems]+"/"+FolderType.FolderNames[FolderType.PublishedFolders])) {
					node = (Node)getSession().getItem(userNode.getPath()
							+"/"+FolderType.FolderNames[FolderType.PublishedItems]
							+"/"+FolderType.FolderNames[FolderType.PublishedFolders]);
				} else {
					node = (Node)getSession().getItem(userNode.getPath()+"/"+FolderType.FolderNames[FolderType.PublishedItems]);
				}
				
				if(node!=null) {
					id = node.getUUID();
				}
			} else if(path.startsWith(FolderType.FolderNames[FolderType.MyNetwork])) {			
				String[] paths = path.split("/");
				
				if(paths.length==1) {
					id = this.getNodeByFolderType(userNode, FolderType.MyNetwork).getUUID();
				} else if(paths.length==2) {
					String ownerId = paths[1];
					Node networkNode = getNodeByFolderType(userNode, FolderType.MyNetwork);
					Node node = networkNode.getNode(ownerId);
					id = node.getUUID();
				} else if(paths.length>=3) {
					String ownerId = paths[1];
					String shortcutPath = userNode.getPath()+"/"+paths[0]+"/"+ownerId+"/"+paths[2];
					Node shortcutNode = (Node)this.getSession().getItem(shortcutPath);
					String originalId = shortcutNode.getProperty("originalId").getString();
					
					if(paths.length==3) {
						id = originalId;
					} else {
						Node originalNode = this.getNodeById(originalId);
						if(originalNode!=null) {
							String subpath = "";
							for(int i=0;i<paths.length-3;i++) {
								subpath += "/" + paths[i+3];
							}
							Node node = (Node)this.getSession().getItem(originalNode.getPath()+subpath);
							if(node!=null) {
								if(this.isFileNode(node)) {
									id = node.getParent().getUUID();
								} else if(this.isFolderNode(node)) {
									id = node.getUUID();
								}
							}
						}
					}				
				}
			}		
		} catch (RepositoryException e) {
		}
		
		return id;
	}
	
	public FolderInfo getFolderInfoById(String userId,String folderId) throws RepositoryException {
		FolderInfo folder = null;
		
		Node node = getNodeById(folderId);
		if(node!=null) {
			folder = this.getFolderInfoByNode(userId,node, new FolderInfo());
		}
		
		return folder;
	}
	
	public FileInfo getFileInfoById(String userId,String fileId) throws RepositoryException {
		FileInfo file = null;
		
		Node node = this.getNodeById(fileId);		
		if(node!=null) {
			//guest user
			if(userId==null) {
				userId = this.getUserIdByItemId(node.getUUID());
			}
			
			file = this.getFileInfoByNode(userId, node, new FileInfo());
		}
			
		return file;
	}
	
	public InputStream getFileContentById(String userId,String fileId) throws RepositoryException {
		InputStream data = null;
		
		Node node = this.getNodeById(fileId);		
		if(node!=null) {
			Node fileNode = node.getNode("file");
			Node resourceNode = fileNode.getNode("jcr:content");
			data = resourceNode.getProperty("jcr:data").getStream();
		}		
		
		return data;
	}
	
	public InputStream getFileThumbnailById(String userId,String fileId) throws RepositoryException {
		InputStream data = null;
		
		Node node = this.getNodeById(fileId);		
		if(node!=null) {
			if(node.hasProperty("thumbnail")) {
				return node.getProperty("thumbnail").getStream();
			}
		}		
		
		return data;
	}
	
	public FolderInfo getParentFolderInfo(String userId,String folderId) throws RepositoryException {
		FolderInfo parent = null;
		
		Node node = getNodeById(folderId);
		if(node!=null) {
			FolderInfo folder = getFolderInfoByNode(userId,node, new FolderInfo());
			if(!FolderType.isTopFolder(folder.getType())) {
				Node parentNode = node.getParent();
				parent = getFolderInfoByNode(userId,parentNode, new FolderInfo());
			}			
		}		
		
		return parent;
	}
	
	public List getFolderListByNode(String userId,boolean save,String nodeId) throws RepositoryException {
		List list = new ArrayList();
		
		Node node = getNodeById(nodeId);
		if(node!=null && node.hasNodes()) {
			if(save) {
				setFolderExpandFlag(userId, node.getUUID(),true);
				save();
			}
			FileInfo info = this.getFileInfoByNode(userId, node, new FileInfo());
			if(info.getFolderType()!=FolderType.PublishedFolders) {
				NodeIterator ni = node.getNodes();
				while(ni.hasNext()) {
					Node child = ni.nextNode();
					if(isFolderNode(child)) {
						FolderInfo childFolder = new FolderInfo();
						childFolder.setParentFolderId(nodeId);
						list.add(getFolderInfoByNode(userId,child, childFolder));
					}
				}
			}			
		}
		
		return list;
	}
	
	public List getFolderListByUser(String userId) throws RepositoryException {
		List list = new ArrayList();
		
		Node userNode = getUserNode(userId);
		
		Node rootFolderNode = getNodeByFolderType(userNode,FolderType.RootFolder);		
		FolderInfo rootFolder = getFolderInfoByNode(userId,rootFolderNode,new FolderInfo(FolderType.RootFolder));
		list.add(rootFolder);
		
		Node publishedFolderNode = getNodeByFolderType(userNode,FolderType.PublishedItems);
		FolderInfo publishedFolder = getFolderInfoByNode(userId,publishedFolderNode,new FolderInfo(FolderType.PublishedItems));
		list.add(publishedFolder);		
		
		Node myNetworkFolderNode = getNodeByFolderType(userNode, FolderType.MyNetwork);
		FolderInfo myNetworkFolder = getFolderInfoByNode(userId,myNetworkFolderNode,new FolderInfo(FolderType.MyNetwork));
		list.add(myNetworkFolder);
		
		return list;
	}
	
	public FileInfo createFolderNode(String userId,String parentId,String name) throws RepositoryException, DuplicateDirectoryException {
		Node parent = this.getNodeById(parentId);
		
		if(parent.hasNode(name)) {
			throw new DuplicateDirectoryException();
		}
		
		this.setFolderExpandFlag(userId, parent.getUUID(),true);		
		Node node = this.createFolderNode(parent, name, name);
		save();
		
		return this.getFileInfoByNode(userId,node, new FileInfo());
	}
	
	public void createFileNode(String userId,String folderId,String fileName,ObservedInputStream input) throws RepositoryException {
		Node parent = this.getNodeById(folderId);
		
		Node node = null;
		if(parent.hasNode(fileName)) {
			node = parent.getNode(fileName);	
			node.setProperty("dateModified", Calendar.getInstance());			
		} else {
			node = this.createFileNode(parent, fileName, fileName);
		}		
		
		if(FolderType.isNeedThumbnail(fileName)) {
			byte[] data = getFileContentBytesByInput(input);
			input = new ObservedInputStream(new ByteArrayInputStream(data));
			InputStream thumbnailInput = ImageResizer.resize(data, FolderType.ThumbnailWidth, FolderType.ThumbnailHeight);
			node.setProperty("thumbnail", thumbnailInput);
		}
		
		MimeTable mt = MimeTable.getDefaultTable();
		String mimeType = mt.getContentTypeFor(fileName);
		if (mimeType == null) {
			mimeType = "application/octet-stream";
		}
		Node fileNode = node.addNode("file", "nt:file");
		Node resourceNode = fileNode.addNode("jcr:content", "nt:resource");
		resourceNode.setProperty("jcr:mimeType", mimeType);
		resourceNode.setProperty("jcr:encoding", "");
		resourceNode.setProperty("jcr:data", input);
		resourceNode.setProperty("jcr:lastModified", Calendar.getInstance());
		
		node.setProperty("size", input.getReadedCount());
		
		save();
	}
	
	private byte[] getFileContentBytesByInput(InputStream input) throws RepositoryException {
		byte[] bytes = new byte[0];
		
		try {
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] buff = new byte[2048];
			int bytesRead;
			while (-1 != (bytesRead = input.read(buff, 0, buff.length))) {
				output.write(buff, 0, bytesRead);
			}
			bytes = output.toByteArray();			
		} catch (IOException e) {
			throw new RepositoryException(e);
		}
		
		return bytes;
	}
	
	public void deleteFolderNodeById(String userId,String folderId) throws RepositoryException {
		Node node = this.getNodeById(folderId);
		if(node!=null) {
			removeNode(userId,node);
		}
	}
	
	public void deleteFileNodeById(String userId,String fileId) throws RepositoryException {
		Node node = this.getNodeById(fileId);
		if(node!=null) {
			removeNode(userId,node);
		}
	}
	
	public void copyFileNode(String userId,String fileId,String targetFolderId) throws RepositoryException {
		Node fileNode = this.getNodeById(fileId);
		Node targetNode = this.getNodeById(targetFolderId);
		
		if(fileNode!=null && targetNode!=null && !fileNode.getParent().equals(targetNode)) {			
			if(targetNode.hasNode(fileNode.getName())) {
				Node existNode = targetNode.getNode(fileNode.getName());
				removeNode(userId,existNode);
				save();
			}
			
			getSession().getWorkspace().copy(fileNode.getPath(), targetNode.getPath()+"/"+fileNode.getName());
			Node newNode = targetNode.getNode(fileNode.getName());
			newNode.setProperty("dateCreated", Calendar.getInstance());
			newNode.setProperty("shared", false);
			newNode.setProperty("published", false);
			
			save();
		}		
	}
	
	public void copyFolderNode(String userId,String folderId,String targetFolderId) throws RepositoryException {
		Node folderNode = this.getNodeById(folderId);
		Node targetNode = this.getNodeById(targetFolderId);
		
		if(folderNode!=null && targetNode!=null && !folderNode.getParent().equals(targetNode)) {
			if(targetNode.hasNode(folderNode.getName())) {
				Node existNode = targetNode.getNode(folderNode.getName());
				for(NodeIterator ni=folderNode.getNodes();ni.hasNext();) {
					Node child = ni.nextNode();
					if(isFileNode(child)) {
						copyFileNode(userId,child.getUUID(),existNode.getUUID());
					} else {
						copyFolderNode(userId,child.getUUID(), existNode.getUUID());
					}
				}
			} else {
				getSession().getWorkspace().copy(folderNode.getPath(), targetNode.getPath()+"/"+folderNode.getName());
				Node newNode = targetNode.getNode(folderNode.getName());
				newNode.setProperty("dateCreated", Calendar.getInstance());
				newNode.setProperty("shared", false);
				newNode.setProperty("published", false);				
				
				//check subfolder and subfile's sharing and publishing flag
				QueryManager qm = getSession().getWorkspace().getQueryManager();
				String sql = "SELECT * FROM nt:unstructured "
							+"WHERE  jcr:path LIKE '"+newNode.getPath()+"/%' "
							+"AND    ( shared = 'true' OR published = 'true' ) ";			
				Query query = qm.createQuery(sql, Query.SQL);			
				QueryResult result = query.execute();
				for(NodeIterator ni=result.getNodes();ni.hasNext();) {
					Node temp = ni.nextNode();
					temp.setProperty("shared", false);
					temp.setProperty("published", false);
				}				
				
				save();
			}
		}
	}
	
	public void moveFileNode(String userId,String fileId,String targetFolderId) throws RepositoryException {
		Node fileNode = this.getNodeById(fileId);
		Node targetNode = this.getNodeById(targetFolderId);
		
		if(fileNode!=null && targetNode!=null && !fileNode.getParent().equals(targetNode)) {
			if(targetNode.hasNode(fileNode.getName())) {
				Node existNode = targetNode.getNode(fileNode.getName());				
				removeNode(userId,existNode);
				save();
			}
			
			if(isPublishedNode(fileNode)) {
				unpublishFile(userId,fileId);
			}
			
			getSession().move(fileNode.getPath(), targetNode.getPath()+"/"+fileNode.getName());
			Node newNode = targetNode.getNode(fileNode.getName());
			newNode.setProperty("dateCreated", Calendar.getInstance());			
			
			save();
		}		
	}
	
	public void moveFolderNode(String userId,String folderId,String targetFolderId) throws RepositoryException {
		Node folderNode = this.getNodeById(folderId);
		Node targetNode = this.getNodeById(targetFolderId);
		
		if(folderNode!=null && targetNode!=null && !folderNode.getParent().equals(targetNode)) {
			if(targetNode.hasNode(folderNode.getName())) {
				Node existNode = targetNode.getNode(folderNode.getName());
				for(NodeIterator ni=folderNode.getNodes();ni.hasNext();) {
					Node child = ni.nextNode();
					if(isFileNode(child)) {
						moveFileNode(userId,child.getUUID(),existNode.getUUID());
					} else {
						moveFolderNode(userId,child.getUUID(), existNode.getUUID());
					}
				}
			} else {
				
				if(isPublishedNode(folderNode)) {
					unpublishFolder(userId,folderId);
				} 
				
				if(isSharedNode(folderNode)) {
					unshareFolder(userId,folderId);
				}
				
				//check subfolder and subfile's sharing and publishing flag
				QueryManager qm = getSession().getWorkspace().getQueryManager();
				String sql = "SELECT * FROM nt:unstructured "
							+"WHERE  jcr:path LIKE '"+folderNode.getPath()+"/%' "
							+"AND    ( shared = 'true' OR published = 'true' ) ";			
				Query query = qm.createQuery(sql, Query.SQL);			
				QueryResult result = query.execute();
				for(NodeIterator ni=result.getNodes();ni.hasNext();) {
					Node temp = ni.nextNode();					
					if(isFileNode(temp)) {
						if(isPublishedNode(temp)) {
							unpublishFile(userId,temp.getUUID());
						}
					} else {
						if(isPublishedNode(temp)) {
							unpublishFolder(userId,temp.getUUID());
						}
						if(isSharedNode(temp)) {
							unshareFolder(userId,temp.getUUID());
						}
					}					
				}
				
				getSession().move(folderNode.getPath(), targetNode.getPath()+"/"+folderNode.getName());
				Node newNode = targetNode.getNode(folderNode.getName());
				newNode.setProperty("dateCreated", Calendar.getInstance());	
				
				save();
			}
		}
	}
	
	public Node registerUser(String userId) throws RepositoryException {
		Node root = getSession().getRootNode();
		Node fileRoot = getFileRootNode(root);
		Node userNode = createUserNode(fileRoot,userId);
		createDefaultFolder(userNode);
		save();
		return userNode;
	}
	
	public boolean isUserRegistered(String userId) {
		Node node = null;
		
		try {
			node = this.getUserNode(userId);
		} catch (RepositoryException e) {			
		}
		
		return node!=null;
	}
	
	public void publishFile(String userId,String fileId,PublishedFileInfo pfi) throws RepositoryException {
		this.setFilePublishFlag(userId,fileId, true);
		this.savePublishedFileInfo(userId, fileId, pfi);
	}
	
	public void publishFolder(String userId,String folderId,PublishedFileInfo pfi) throws RepositoryException {
		this.setFolderPublishFlag(userId, folderId, true);
		this.savePublishedFileInfo(userId, folderId, pfi);
	}	
	
	public void unpublishFile(String userId,String fileId) throws RepositoryException {
		this.setFilePublishFlag(userId,fileId, false);
	}
	
	public void unpublishFolder(String userId,String folderId) throws RepositoryException {
		this.setFolderPublishFlag(userId, folderId, false);
	}
	
	public PublishedFileInfo getPublishedFileInfo(String userId,String fileId) throws RepositoryException {
		PublishedFileInfo info = new PublishedFileInfo();
		
		Node node = this.getNodeById(fileId);		
		if(node!=null) {
			if(node.hasProperty("enableExpiration")) {
				info.setEnableExpiration(node.getProperty("enableExpiration").getBoolean());
			}
			if(node.hasProperty("expireDate")) {
				info.setExpireDate(node.getProperty("expireDate").getString());
			} else {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
				String date = sdf.format(Calendar.getInstance().getTime());
				info.setExpireDate(date);
			}
			if(node.hasProperty("enablePassword")) {
				info.setEnablePassword(node.getProperty("enablePassword").getBoolean());
			}
			if(node.hasProperty("password")) {
				info.setPassword(node.getProperty("password").getString());
			}
			if(node.hasProperty("enableComment")) {
				info.setEnableComment(node.getProperty("enableComment").getBoolean());
			}
			if(node.hasProperty("comment")) {
				info.setComment(node.getProperty("comment").getString());
			}
		}
		
		return info;
	}
	
	public boolean isFileInPublishedFolder(String userId,String fileId) throws RepositoryException {
		boolean published = false;
		
		Node node = this.getNodeById(fileId);		
		if(node!=null) {
			if(this.isPublishedNode(node)) {
				published = true;
			} else {				
				FileInfo info = this.getFileInfoById(userId, node.getUUID());
				while(!published && !FolderType.isTopFolder(info.getFolderType())) {
					if(info.isPublished()) {
						published = true;
						break;
					} 
					node = node.getParent();
					info = this.getFileInfoById(userId, node.getUUID());
				}
			}						
		}
		
		return published;
	}
	
	public void shareFolder(String userId,String folderId,List<SharedFilePermission> permissions,String comment) throws RepositoryException {
		this.setFolderSharedFlag(userId,folderId, true, permissions, comment);
	}
	
	public void unshareFolder(String userId,String folderId) throws RepositoryException {
		this.setFolderSharedFlag(userId,folderId, false, null, "");
	}	
	
	public List<SharedFilePermission> getSharedFilePermissions(String folderId) throws RepositoryException {
		List<SharedFilePermission> permissions = new ArrayList();
		
		Node folderNode = this.getNodeById(folderId);
		if(this.isSharedNode(folderNode)) {
			if(folderNode.hasProperty("prmUserIds")) {
				Value[] prmUserIds = folderNode.getProperty("prmUserIds").getValues();
				Value[] prmAccessTypes = folderNode.getProperty("prmAccessTypes").getValues();
				for(int i=0;i<prmUserIds.length;i++) {
					SharedFilePermission permission = new SharedFilePermission();
					permission.setFolderID(folderId);
					permission.setUserName(prmUserIds[i].getString());
					permission.setUserAccessType(Integer.parseInt(prmAccessTypes[i].getString()));
					permission.setNotify(true);
					permissions.add(permission);
				}
			}			
		}
		
		return permissions;
	}
	
	public void rename(String userId,String fileId,String name) throws RepositoryException {
		Node node = this.getNodeById(fileId);
		if(node!=null) {
			Node parentNode = node.getParent();
			if(isFileNode(node)) {
				Node newNode = createFileNode(parentNode, name, name);				
				newNode.setProperty("dateCreated", node.getProperty("dateCreated").getDate());
				newNode.setProperty("dateModified", Calendar.getInstance());
				newNode.setProperty("description", node.getProperty("description").getString());
				newNode.setProperty("size", node.getProperty("size").getLong());
				
				getSession().move(node.getPath()+"/file", newNode.getPath()+"/file");
				
				removeNode(userId,node);
			} else if(isFolderNode(node)) {
				Node newNode = createFolderNode(parentNode, name, name);				
				newNode.setProperty("dateCreated", node.getProperty("dateCreated").getDate());
				newNode.setProperty("dateModified", Calendar.getInstance());
				newNode.setProperty("description", node.getProperty("description").getString());
				
				List<Node> nodes = new ArrayList();
				for(NodeIterator ni = node.getNodes();ni.hasNext();) {
					nodes.add(ni.nextNode());					
				}
				for(int i=0;i<nodes.size();i++) {
					getSession().move(nodes.get(i).getPath(), newNode.getPath()+"/"+nodes.get(i).getName());
				}
				
				removeNode(userId,node);
			}			
		}
	}
	
	public List findFileListByKeyword(String userId,String keyword) throws RepositoryException {
		List files = new ArrayList();
		
		Node userNode = getUserNode(userId);
		Node rootFolderNode = getNodeByFolderType(userNode,FolderType.RootFolder);
		
		String sql = "SELECT * FROM nt:unstructured "
					+"WHERE  jcr:path LIKE '"+rootFolderNode.getPath()+"/%' "
					+"AND    name LIKE '%"+keyword+"%' ";
		QueryManager qm = getSession().getWorkspace().getQueryManager();
		Query query = qm.createQuery(sql, Query.SQL);
		
		QueryResult result = query.execute();		
		NodeIterator it = result.getNodes();
		while (it.hasNext()) {
			Node node = it.nextNode();
			FileInfo file = this.getFileInfoById(userId,node.getUUID());
			if(file!=null) {
				files.add(file);
			}
		}

		return files;
	}
	
	public long getFolderSize(String folderId) throws RepositoryException {
		long size = 0;		
		
		Node folderNode = getNodeById(folderId);		
		if(folderNode!=null) {
			String sql = "SELECT * FROM nt:unstructured "
						+"WHERE  jcr:path LIKE '"+folderNode.getPath()+"/%' "
						+"AND    folder = 'false' ";
			QueryManager qm = getSession().getWorkspace().getQueryManager();
			Query query = qm.createQuery(sql, Query.SQL);
			
			QueryResult result = query.execute();		
			NodeIterator it = result.getNodes();
			while (it.hasNext()) {
				Node node = it.nextNode();
				if(isFileNode(node)) {
					size += node.getProperty("size").getLong();
				}				
			}
		}		

		return size;
	}
	
	public long getSubFileCount(String folderId) throws RepositoryException {
		long count = 0;
		
		Node folderNode = getNodeById(folderId);		
		if(folderNode!=null) {
			String sql = "SELECT * FROM nt:unstructured "
						+"WHERE  jcr:path LIKE '"+folderNode.getPath()+"/%' "
						+"AND    folder = 'false' ";
			QueryManager qm = getSession().getWorkspace().getQueryManager();
			Query query = qm.createQuery(sql, Query.SQL);
			
			QueryResult result = query.execute();		
			count = result.getNodes().getSize();			
		}
		
		return count;
	}
	
	public long getSubFolderCount(String folderId) throws RepositoryException {
		long count = 0;
		
		Node folderNode = getNodeById(folderId);		
		if(folderNode!=null) {
			String sql = "SELECT * FROM nt:unstructured "
						+"WHERE  jcr:path LIKE '"+folderNode.getPath()+"/%' "
						+"AND    folder = 'true' ";
			QueryManager qm = getSession().getWorkspace().getQueryManager();
			Query query = qm.createQuery(sql, Query.SQL);
			
			QueryResult result = query.execute();		
			count = result.getNodes().getSize();			
		}
		
		return count;
	}
	
	public String getUserIdByItemId(String itemId) throws RepositoryException {
		String userId = null;
		
		Node node = this.getNodeById(itemId);
		if(node!=null) {
			userId = this.getUserNodeByItemNode(node).getName();
		}
		
		return userId;
	}
	
	public boolean isParentFolder(String folderId,String itemId) throws RepositoryException {
		boolean result = false;
		
		Node node = this.getNodeById(itemId);
		if(node!=null) {
			while(node.getParent()!=null && !node.getParent().getUUID().equals(folderId)) {
				node = node.getParent();
			}
			if(node!=null && this.isFolderNode(node)) {
				result = true;
			}
		}
		
		return result;
	}
	
	public void setFolderExpandFlag(String userId,String folderId, boolean expanded) throws RepositoryException {
		Node profileNode = this.getUserProfileNode(userId);
		
		for(NodeIterator ni=profileNode.getNodes();ni.hasNext();) {
			Node node = ni.nextNode();
			String uuid = node.getName();
			if(getNodeById(uuid)==null) {
				node.remove();
			}
		}
		if(expanded) {
			Node node = null;
			if(profileNode.hasNode(folderId)) {
				node = profileNode.getNode(folderId);
			} else {
				node = profileNode.addNode(folderId);
			}
			node.setProperty("expanded", true);
		} else {
			if(profileNode.hasNode(folderId)) {
				Node node = profileNode.getNode(folderId);
				node.remove();
			}
		}		
	}
	
	public boolean isFolderExpanded(String userId,String folderId) throws RepositoryException {
		boolean expanded = false;
		
		Node profileNode = this.getUserProfileNode(userId);
		if(profileNode.hasNode(folderId)) {
			Node node = profileNode.getNode(folderId);
			if(node.hasProperty("expanded")) {
				expanded = node.getProperty("expanded").getBoolean();
			}
		}
		
		return expanded;
	}
	
	public boolean isFileModifiable(String userId,String fileId) throws RepositoryException {
		return getFileAccessType(userId, fileId) == SharedFilePermission.USER_ACCESS_TYPE_ALL;
	}
	
	private void setFolderSharedFlag(String userId,String folderId,boolean shared,List<SharedFilePermission> permissions,String comment) throws RepositoryException {
		Node node = this.getNodeById(folderId);
		
		if(node!=null) {
			node.setProperty("shared", shared);			
			
			FileInfo info = this.getFileInfoById(userId,folderId);
			Node currentUserNode = this.getUserNodeByItemNode(node);
			if(shared) {
				String[] prmUserIds = new String[permissions.size()];
				String[] prmAccessTypes = new String[permissions.size()];
				for(int i=0;i<permissions.size();i++) {
					String userName = permissions.get(i).getUserName();
					int accessType = permissions.get(i).getUserAccessType();
					prmUserIds[i] = userName;
					prmAccessTypes[i] = String.valueOf(accessType);
					
					if(!isUserRegistered(userName)) {
						registerUser(userName);
					}
					Node userNode = this.getUserNodeById(userName);
					Node networkNode = this.getNodeByFolderType(userNode, FolderType.MyNetwork);
					Node networkUserNode = null;
					if(networkNode.hasNode(currentUserNode.getName())) {
						networkUserNode = networkNode.getNode(currentUserNode.getName());
					} else {
						networkUserNode = this.createFolderNode(networkNode, currentUserNode.getName(), currentUserNode.getName());
					}
					networkUserNode.setProperty("folderType", FolderType.MyNetworkUser);
					
					Node sharedFolderNode = null;
					for(NodeIterator ni=networkUserNode.getNodes();ni.hasNext();) {
						Node temp = ni.nextNode();
						if(temp.hasProperty("shortcut") && temp.getProperty("shortcut").getBoolean()) {
							if(temp.getProperty("originalId").getString().equals(folderId)) {
								sharedFolderNode = temp;
							}
						}
					}
					if(sharedFolderNode==null) {
						sharedFolderNode = this.createFolderNode(networkUserNode,info.getName(),info.getName());
						sharedFolderNode.setProperty("folderType", FolderType.SharedDocuments);
						sharedFolderNode.setProperty("shortcut", true);
						sharedFolderNode.setProperty("originalId", node.getUUID());
					}					
				}
				
				node.setProperty("description", comment);				
				node.setProperty("prmUserIds", prmUserIds);
				node.setProperty("prmAccessTypes", prmAccessTypes);
			} else {
				if(node.hasProperty("prmUserIds")) {
					Value[] prmUserIds = node.getProperty("prmUserIds").getValues();
					for(int i=0;i<prmUserIds.length;i++) {
						String userName = prmUserIds[i].getString();	
						Node userNode = this.getUserNodeById(userName);
						Node networkNode = this.getNodeByFolderType(userNode, FolderType.MyNetwork);
						for(NodeIterator iterator=networkNode.getNodes(currentUserNode.getName());iterator.hasNext();) {
							Node networkUserNode = iterator.nextNode();
							for(NodeIterator ni=networkUserNode.getNodes();ni.hasNext();) {
								Node temp = ni.nextNode();
								if(temp.getProperty("originalId").getString().equals(node.getUUID())) {
									temp.remove();
								}
							}
							if(!networkUserNode.hasNodes()) {
								networkUserNode.remove();
							}
						}						
					}
				}
				String[] prmUserIds = new String[0];
				String[] prmAccessTypes = new String[0];
				node.setProperty("description", "");
				node.setProperty("prmUserIds", prmUserIds);
				node.setProperty("prmAccessTypes", prmAccessTypes);
			}
		}
	}
	
	private SharedFilePermission getSharedFilePermission(String userId,String fileId) throws RepositoryException {
		SharedFilePermission permission = null;
		
		Node node = this.getNodeById(fileId);
		if(node!=null) {
			String folderId = fileId;
			if(isFileNode(node)) {
				folderId = node.getParent().getUUID();
			}
			
			Node folderNode = this.getNodeById(folderId);			
			int folderType = (int)folderNode.getProperty("folderType").getLong();
			while(!FolderType.isTopFolder(folderType) && permission==null) {
				if(isSharedNode(folderNode)) {
					List<SharedFilePermission> permissions = getSharedFilePermissions(folderNode.getUUID());
					for(int i=0;i<permissions.size();i++) {
						SharedFilePermission prm = permissions.get(i);
						if(prm.getUserName().equals(userId)) {
							permission = prm;
							break;
						}
					}
				}
				folderNode = folderNode.getParent();
				folderType = (int)folderNode.getProperty("folderType").getLong();
			}
		}
		
		return permission;
	}
	
	private int getFileAccessType(String userId,String fileId) throws RepositoryException {
		int type = SharedFilePermission.USER_ACCESS_TYPE_NONE;		
		
		Node node = this.getNodeById(fileId);
		if(node!=null) {		
			String ownerId = this.getUserIdByItemId(fileId);
			if(ownerId.equals(userId)) {
				type = SharedFilePermission.USER_ACCESS_TYPE_ALL;
			} else {
				SharedFilePermission permission = getSharedFilePermission(userId, fileId);
				if(permission!=null) {
					type = permission.getUserAccessType();
				} 
			}
		}
		
		return type;
	}
	
	private void setFilePublishFlag(String userId,String fileId,boolean published) throws RepositoryException {
		Node node = this.getNodeById(fileId);
		
		if(node!=null) {
			node.setProperty("published", published);
			
			Node userNode = this.getUserNodeByItemNode(node);
			Node publisedItems = getNodeByFolderType(userNode, FolderType.PublishedItems);
			Node publisedFiles = publisedItems.getNode(FolderType.FolderNames[FolderType.PublishedFiles]);
			
			Node existNode = null;
			for(NodeIterator ni = publisedFiles.getNodes();ni.hasNext();) {
				Node temp = ni.nextNode();
				String originalId = temp.getProperty("originalId").getString();
				if(node.getUUID().equals(originalId)) {
					existNode = temp;
					break;
				}
			}
			
			if(published && existNode==null) {								
				FileInfo info = this.getFileInfoById(userId,fileId);
				Node shortCutNode = createFileNode(publisedFiles, info.getName(), info.getName());
				shortCutNode.setProperty("shortcut", true);
				shortCutNode.setProperty("originalId", node.getUUID());								
			} else if(!published && existNode!=null) {
				existNode.remove();
			}			
		}
	}
	
	private void setFolderPublishFlag(String userId,String folderId,boolean published) throws RepositoryException {
		Node node = this.getNodeById(folderId);
		
		if(node!=null) {
			node.setProperty("published", published);
			
			Node userNode = this.getUserNodeByItemNode(node);
			Node publisedItems = getNodeByFolderType(userNode, FolderType.PublishedItems);
			Node publisedFolders = publisedItems.getNode(FolderType.FolderNames[FolderType.PublishedFolders]);
			
			Node existNode = null;
			for(NodeIterator ni = publisedFolders.getNodes();ni.hasNext();) {
				Node temp = ni.nextNode();
				String originalId = temp.getProperty("originalId").getString();
				if(node.getUUID().equals(originalId)) {
					existNode = temp;
					break;
				}
			}
			
			if(published && existNode==null) {								
				FileInfo info = this.getFileInfoById(userId,folderId);
				Node shortCutNode = createFolderNode(publisedFolders, info.getName(), info.getName());
				shortCutNode.setProperty("shortcut", true);
				shortCutNode.setProperty("originalId", node.getUUID());								
			} else if(!published && existNode!=null) {
				existNode.remove();
			}			
		}
	}
	
	private void savePublishedFileInfo(String userId,String fileId,PublishedFileInfo pfi) throws RepositoryException {
		Node node = this.getNodeById(fileId);
		
		if(node!=null && pfi!=null) {
			node.setProperty("enableExpiration", pfi.isEnableExpiration());
			node.setProperty("expireDate", pfi.getExpireDate());
			node.setProperty("enablePassword", pfi.isEnablePassword());
			node.setProperty("password", pfi.getPassword());
			node.setProperty("enableComment", pfi.isEnableComment());
			node.setProperty("comment", pfi.getComment());
		}		
	}
	
	private String getFolderPathByNode(String userId,Node node,String childPath) throws RepositoryException {
		String path = childPath;
		
		if(node!=null) {
			FolderInfo folder = this.getFolderInfoByNode(userId, node, new FolderInfo());
			
			//test if top level path
			if(!FolderType.isTopFolder(folder.getType())) {
				path = path.length()>0 ? folder.getText()+"\\"+path : folder.getText(); 
				FolderInfo parent = this.getParentFolderInfo(userId,node.getUUID());
				if(parent!=null) {
					path = this.getFolderPathByNode(userId, node.getParent(), path);
				}
			} else {
				path = folder.getText() + ":" + (path!=null && path.length()>0? "\\" : "") + path;				
			}
		}
		
		return path;
	}
	
	private FileInfo getFileInfoByNode(String userId,Node node,FileInfo file) throws RepositoryException {
		
		if(node!=null && node.hasProperty("folder")) {		
			file.setId(node.getUUID());
			file.setFolder(node.getProperty("folder").getBoolean());
			if(node.hasProperty("name")) {
				file.setName(node.getProperty("name").getString());
			}			
			if(node.hasProperty("size")) {				
				file.setSize(node.getProperty("size").getLong());
			}
			if(node.hasProperty("folderType")) {			
				file.setFolderType((int)node.getProperty("folderType").getLong());
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			if(node.hasProperty("dateCreated")) {				
				Date date = node.getProperty("dateCreated").getDate().getTime();
				file.setDateCreated(sdf.format(date));
			}
			if(node.hasProperty("dateModified")) {		
				Date date = node.getProperty("dateModified").getDate().getTime();
				file.setDateModified(sdf.format(date));
			}
			if(node.hasProperty("description")) {
				file.setDescription(node.getProperty("description").getString());
			}
			if(node.hasProperty("shared")) {
				file.setShared(node.getProperty("shared").getBoolean());
			}
			if(node.hasProperty("published")) {
				file.setPublished(node.getProperty("published").getBoolean());
			}
			if(FolderType.isTopFolder(file.getFolderType())) {
				file.setPath("");
			} else {
				file.setPath(getFolderPathById(userId,node.getParent().getUUID()));	
			}					
		} else {
			file = null;
		}
		
		return file;
	}
	
	private FolderInfo getFolderInfoByNode(String userId,Node node,FolderInfo folder) throws RepositoryException {
		
		if(node.hasProperty("folder") && node.getProperty("folder").getBoolean()) {
			
			if(node.hasProperty("shortcut") && node.getProperty("shortcut").getBoolean()) {
				String originalId = node.getProperty("originalId").getString();
				node = this.getNodeById(originalId);				
			}
			
			if(node!=null) {
				folder.setId(node.getUUID());
				if(node.hasProperty("name")) {
					folder.setText(node.getProperty("name").getString());
				}			
				if(node.hasProperty("shared")) {
					folder.setShared(node.getProperty("shared").getBoolean());
				}
				if(node.hasProperty("folderType")) {
					folder.setType((int)node.getProperty("folderType").getLong());
					if(folder.getType()==FolderType.FileFolder) {
						String ownerId = this.getUserIdByItemId(node.getUUID());						
						if(userId!=null && !userId.equals(ownerId)) {
							folder.setType(FolderType.SharedFolder);
						}
					}					
				}
				
				folder.setExpanded(isFolderExpanded(userId, node.getUUID()));
				if(folder.isExpanded() && node.hasNodes() && folder.getType()!=FolderType.PublishedFolders) {
					List subFolders = new ArrayList();
					NodeIterator ni = node.getNodes();
					while(ni.hasNext()) {
						Node child = ni.nextNode();
						if(isFolderNode(child)) {
							subFolders.add(getFolderInfoByNode(userId,child, new FolderInfo()));
						}					
					}
					folder.setChildren(subFolders);
				}
			}				
		}
		
		return folder;
	}
	
	private Node getFileRootNode(Node root) throws RepositoryException {		
		Node fileRoot = null;
		
		if(root.hasNode("file")) {
			fileRoot = root.getNode("file");
		}		
		if(fileRoot==null) {
			fileRoot = createNode(root,"file");
		}		
		
		return fileRoot;
	}	
	
	private Node getUserNode(String userId) throws RepositoryException {		
		Node root = getSession().getRootNode();
		return root.getNode(NodePath_File+"/"+userId);		
	}
	
	private Node getUserNodeById(String userId) throws RepositoryException {		
		Node root = getSession().getRootNode();
		return root.getNode(NodePath_File+"/"+userId);		
	}
	
	private Node getUserNodeByItemNode(Node node) throws RepositoryException {
		String fullPath = node.getPath();
		
		String[] paths = fullPath.split("/");
		String userPath = "/"+paths[1]+"/"+paths[2];
		Node userNode = (Node)getSession().getItem(userPath);
		
		return userNode;
	}
	
	private Node getUserProfileNode(String userId) throws RepositoryException {		
		Node userNode = this.getUserNode(userId);
		
		if(!userNode.hasNode("profile")) {
			userNode.addNode("profile");
			save();
		}
		
		return userNode.getNode("profile");
	}
	
	private Node getNodeByFolderType(Node parent,int folderType) throws RepositoryException {
		return parent.getNode(FolderType.FolderNames[folderType]);
	}
	
	private void createDefaultFolder(Node userNode) throws RepositoryException {
		Node rootFolder = createSystemFolderNode(userNode,FolderType.RootFolder);
		createFolderNode(rootFolder,"My Document","My Document");
		createFolderNode(rootFolder,"My Picture","My Picture");
		createFolderNode(rootFolder,"My Music","My Music");		
		
		createSystemFolderNode(userNode,FolderType.RecycleBin);
		createSystemFolderNode(userNode,FolderType.MyNetwork);
		createSystemFolderNode(userNode,FolderType.SharedDocuments);
		
		Node publishedFolder = createSystemFolderNode(userNode,FolderType.PublishedItems);
		createSystemFolderNode(publishedFolder, FolderType.PublishedFiles);
		createSystemFolderNode(publishedFolder, FolderType.PublishedFolders);
		
		createSystemFolderNode(userNode,FolderType.TagsFolder);
		createSystemFolderNode(userNode,FolderType.TempFolder);		
	}
	
	private Node createUserNode(Node parent,String userId) throws RepositoryException {
		return createNode(parent,userId);
	}
	
	private Node createSystemFolderNode(Node parent,int folderType) throws RepositoryException {
		Node node = createFolderNode(parent, FolderType.FolderNames[folderType], FolderType.FolderNames[folderType]);
		
		node.setProperty("folderType", folderType);		
		
		return node;
	}
	
	private Node createFolderNode(Node parent,String path,String name) throws RepositoryException {
		Node node = createFileItemNode(parent,path,name);
		
		node.setProperty("folder", true);		
		
		return node;
	}
	
	private Node createFileNode(Node parent,String path,String name) throws RepositoryException {
		Node node = createFileItemNode(parent,path,name);
		
		node.setProperty("folder", false);
		
		return node;
	}
	
	private Node createFileItemNode(Node parent,String path,String name) throws RepositoryException {
		Node node = createNode(parent,path);
		
		node.setProperty("id", node.getUUID());
		node.setProperty("name", name);
		node.setProperty("folder", true);
		node.setProperty("folderType", FolderType.FileFolder);
		node.setProperty("size", 0);
		node.setProperty("dateCreated", Calendar.getInstance());
		node.setProperty("dateModified", Calendar.getInstance());
		node.setProperty("description", "");
		node.setProperty("shared", false);
		node.setProperty("published", false);
		
		return node;
	}
	
	private Node createNode(Node parent,String path) throws RepositoryException {
			
		Node node = parent.addNode(path);
		node.addMixin("mix:referenceable");
		
		return node;		
	}
	
	private void removeNode(String userId,Node node) throws RepositoryException {
		
		if(isFileNode(node)) {
			if(isPublishedNode(node)) {
				unpublishFile(userId,node.getUUID());
			}
		} else if(isFolderNode(node)) {
			if(isSharedNode(node)) {	
				unshareFolder(userId,node.getUUID());
			}
			if(isPublishedNode(node)) {
				unpublishFolder(userId,node.getUUID());
			}
			
			QueryManager qm = getSession().getWorkspace().getQueryManager();
			//check subfolder's sharing flag
			String sql = "SELECT * FROM nt:unstructured "
						+"WHERE  jcr:path LIKE '"+node.getPath()+"/%' "
						+"AND    folder = 'true' "
						+"AND    shared = 'true' ";			
			Query query = qm.createQuery(sql, Query.SQL);			
			QueryResult result = query.execute();
			for(NodeIterator ni=result.getNodes();ni.hasNext();) {
				Node temp = ni.nextNode();
				unshareFolder(userId,temp.getUUID());
			}			
			
			//check subfolder's publishing flag
			sql = "SELECT * FROM nt:unstructured "
				+ "WHERE  jcr:path LIKE '"+node.getPath()+"/%' "
				+ "AND    folder = 'true' "
				+ "AND    published = 'true' ";
			query = qm.createQuery(sql, Query.SQL);			
			result = query.execute();
			for(NodeIterator ni=result.getNodes();ni.hasNext();) {
				Node temp = ni.nextNode();
				unpublishFolder(userId,temp.getUUID());
			}
			
			//check subfile's publishing flag
			sql = "SELECT * FROM nt:unstructured "
				+ "WHERE  jcr:path LIKE '"+node.getPath()+"/%' "
				+ "AND    folder = 'false' "
				+ "AND    published = 'true' ";
			query = qm.createQuery(sql, Query.SQL);			
			result = query.execute();
			for(NodeIterator ni=result.getNodes();ni.hasNext();) {
				Node temp = ni.nextNode();
				unpublishFile(userId,temp.getUUID());
			}
		}
		
		node.remove();
	}	
	
	private boolean isFileNode(Node node) {
		boolean result = false;
		
		try {
			result = node!=null && node.hasProperty("folder") && !node.getProperty("folder").getBoolean();
		} catch (Exception e) {			
		} 
		
		return result;
	}
	
	private boolean isFolderNode(Node node) {
		boolean result = false;
		
		try {
			result = node!=null && node.hasProperty("folder") && node.getProperty("folder").getBoolean();
		} catch (Exception e) {			
		} 
		
		return result;
	}
	
	private boolean isSharedNode(Node node) {
		boolean result = false;
		
		try {
			result = node!=null && node.hasProperty("shared") && node.getProperty("shared").getBoolean();
		} catch (Exception e) {			
		} 
		
		return result;
	}
	
	private boolean isPublishedNode(Node node) {
		boolean result = false;
		
		try {
			result = node!=null && node.hasProperty("published") && node.getProperty("published").getBoolean();
		} catch (Exception e) {			
		} 
		
		return result;
	}
	
	private Node getNodeById(String id) {
		Node node = null;
		
		try {
			node = getSession().getNodeByUUID(id);
		} catch (Exception e) {
		} 
		
		return node;
	}
}
